﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 华容道
{
    public class Aspect
    {
        public List<Block> bs = null;
        public int th = 0;
        public Tuple<int, int, Turn> step = null;
        public Aspect parent = null;
        public bool success = false;

        /// <summary>
        /// 默认是横刀立马局面
        /// </summary>
        public Aspect()
        {
            bs = new()
            {
                new Block(0, 0, 1, 2, 3),
                new Block(0, 1, 2, 2, 4),
                new Block(0, 3, 1, 2, 3),
                new Block(2, 0, 1, 2, 3),
                new Block(2, 3, 1, 2, 3),
                new Block(3, 1, 1, 1, 1),
                new Block(2, 1, 2, 1, 2),
                new Block(3, 2, 1, 1, 1),
                new Block(4, 0, 1, 1, 1),
                new Block(4, 3, 1, 1, 1),
            };
        }

        public Aspect(Aspect aspect, Tuple<int, int, Turn> step)
        {
            bs = new();
            Block may = null;
            for (int i = 0; i < aspect.bs.Count; i++)
            {
                var b = aspect.bs[i];
                bs.Add(new(b));
                if (b.x == step.Item1 && b.y == step.Item2)
                {
                    may = bs[i];
                }
            }

            th = aspect.th + 1;
            this.step = step;
            parent = aspect;

            switch (step.Item3)
            {
                case Turn.LEFT:
                    may.y--;
                    break;
                case Turn.RIGHT:
                    may.y++;
                    break;
                case Turn.DOWN:
                    may.x++;
                    break;
                case Turn.UP:
                    may.x--;
                    break;
            }

            success = (may.type == 4 && may.x == 3 && may.y == 1);
        }

        public int[,] Map()
        {
            int[,] map = new int[5, 4];
            foreach (var b in bs)
            {
                for (int i = b.x; i < b.x + b.height; i++)
                {
                    for (int j = b.y; j < b.y + b.width; j++)
                    {
                        map[i, j] = b.type;
                    }
                }
            }
            return map;
        }

        public List<Tuple<int, int, Turn>> Steps(int[,] map)
        {
            List<Tuple<int, int, Turn>> rs = new();
            foreach (var b in bs)
            {
                if (b.CanUp(map))
                {
                    rs.Add(new(b.x, b.y, Turn.UP));
                }

                if (b.CanDown(map))
                {
                    rs.Add(new(b.x, b.y, Turn.DOWN));
                }

                if (b.CanLeft(map))
                {
                    rs.Add(new(b.x, b.y, Turn.LEFT));
                }

                if (b.CanRight(map))
                {
                    rs.Add(new(b.x, b.y, Turn.RIGHT));
                }
            }
            return rs;
        }

        public override string ToString()
        {
            int[,] map = Map();
            //空格，曹操，横將，竖将
            StringBuilder sb = new();

            for (int i = 0; i < 5; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    if (map[i, j] == 0)
                    {
                        sb.Append((char)(i * 10 + j));
                        map[i, j] = 10;
                    }
                }
            }

            for (int i = 0; i < 5; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    if (map[i, j] == 4)
                    {
                        sb.Append((char)(i * 10 + j));
                        map[i, j] = 10;
                        map[i, j + 1] = 10;
                        map[i + 1, j] = 10;
                        map[i + 1, j + 1] = 10;
                    }
                }
            }

            for (int i = 0; i < 5; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    if (map[i, j] == 2)
                    {
                        sb.Append((char)(i * 10 + j));
                        map[i, j] = 10;
                        map[i, j + 1] = 10;
                    }
                }
            }

            for (int i = 0; i < 5; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    if (map[i, j] == 3)
                    {
                        sb.Append((char)(i * 10 + j));
                        map[i, j] = 10;
                        map[i + 1, j] = 10;
                    }
                }
            }

            return sb.ToString();
        }
    }

    public enum Turn
    {
        LEFT,
        RIGHT,
        UP,
        DOWN
    }
}
